package org.mercworks.knight.util;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import org.mercworks.knight.textures.KnightImage;

public class TextureUtils
{
	/**
	 * Allocate a texture (glGenTextures) and return the handle to it.
	 */
	public static int allocateTexture()
	{
		IntBuffer textureHandle = AllocationUtil.allocInts(1);
		GL11.glGenTextures(textureHandle);
		return textureHandle.get(0);
	}

	/**
	 * Create a texture from the given image.
	 */
	public static int makeTexture(KnightImage knightImage)
	{

		if (knightImage == null)
		{
			return 0;
		}
		else
		{
			return makeTexture(knightImage.pixelBuffer, knightImage.w, knightImage.h);
		}
	}

	/**
	 * How many times to repeat texture horizontally and vertically.
	 */
	// public static void setTextureTile(float horizontalTile, float verticalTile)
	// {
	// tileFactorHoriz = horizontalTile;
	// tileFactorVert = verticalTile;
	// }
	/**
	 * Create a texture from the given pixels in RGBA format. Set the texture to
	 * repeat in both directions and use LINEAR for magnification.
	 * 
	 * @return the texture handle
	 */
	public static int makeTexture(ByteBuffer pixels, int w, int h)
	{
		// get a new empty texture
		int textureHandle = allocateTexture();
		// 'select' the new texture by it's handle
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureHandle);
		// set texture parameters
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S,
				GL11.GL_REPEAT);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T,
				GL11.GL_REPEAT);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER,
				GL11.GL_LINEAR); // GL11.GL_NEAREST);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,
				GL11.GL_LINEAR); // GL11.GL_NEAREST);
		// Create the texture from pixels
		GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, w, h, 0,
				GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixels);
		return textureHandle;
	}

	/**
	 * Build Mipmaps for texture (builds different versions of the picture for
	 * distances - looks better)
	 * 
	 * @param knightImage
	 *          the texture image
	 * @return error code of buildMipMap call
	 */
	public static int makeTextureMipMap(KnightImage knightImage)
	{
		int ret = GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, 4, knightImage.w, knightImage.h, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, knightImage.getPixelsRGBA());
		if (ret != 0)
		{
			System.out
					.println("GLApp.makeTextureMipMap(): Error occured while building mip map, ret="
							+ ret);
		}
		// Assign the mip map levels and texture info
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,
				GL11.GL_LINEAR_MIPMAP_NEAREST);
		GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE,
				GL11.GL_MODULATE);
		return ret;
	}
}
